package com.only4play.practice.common.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.HorizontalAlignment;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author mengdy
 */
@Slf4j
public class EasyExcelUtils {

    private static final String EXCEL_XLS = ".xls";
    private static final String EXCEL_XLSX = ".xlsx";
    /**
     *
     * @param response 响应对象
     * @param fileName 要导出的文件名
     * @param sheetName sheet名称
     * @param data 要导出的数据
     * @param clazz 要导出的数据类型
     * @param writeCellStyle 自定义写入的样式类型
     * @throws IOException IO异常
     */
    public static <T> void exportNormalExcel2Front(HttpServletResponse response,String fileName, String sheetName,List<T> data , Class<T> clazz,WriteCellStyle writeCellStyle) throws IOException {

        // response 不能重复写入响应，否则会报错 [前端调用的导出方法不能有二级以上的调用链路]
//        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        if (StringUtils.isEmpty(fileName)) {
            fileName = "导出表格" + DateUtils.format(new Date(), DateFormatUtils.PATTERN_CLASSICAL_yyyyMMddHHmm);
        }
        if (StringUtils.isEmpty(sheetName)) {
            sheetName = "Sheet1";
        }
        //内容样式
        WriteCellStyle contentWriteCellStyle = null;
        if (writeCellStyle == null){
            //表头样式
            writeCellStyle = new WriteCellStyle();
            //设置表头居中对齐
            writeCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            //表头大小
            WriteFont headWriteFont = new WriteFont();
            headWriteFont.setFontHeightInPoints((short) 11);
            writeCellStyle.setWriteFont(headWriteFont);

            contentWriteCellStyle = new WriteCellStyle();
            //设置内容靠左对齐
            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        }

        try {
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(writeCellStyle, contentWriteCellStyle);
            EasyExcel.write(getOutputStream(fileName, response), clazz).autoCloseStream(Boolean.TRUE)
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .sheet(sheetName)
                    .doWrite(data);
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("code", "-1");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        }
    }
    /**
     * 流方式响应给前端
     * @param fileName
     * @param response
     * @return
     * @throws Exception
     */
    private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + EXCEL_XLSX);
        response.setStatus(HttpServletResponse.SC_OK);
        return response.getOutputStream();
    }


    public static void main(String[] args) {

    }
}
